package com.fary.consumer;

import cn.hutool.json.JSONUtil;
import com.fary.bo.NotifyMerchantBO;
import com.fary.entity.ConsumerLog;
import com.fary.service.ConsumerLogService;
import com.fary.service.PayMessageTemplateService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

import static com.fary.constant.RabbitMQExchangeConstant.RETRY_EXCHANGE;
import static com.fary.constant.RabbitMQExchangeConstant.WECHAT_BATCH_TEMPLATE_EXCHANGE;
import static com.fary.constant.RabbitMQQueueConstant.WECHAT_BATCH_TEMPLATE_QUEUE;

@Component
@Slf4j
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = WECHAT_BATCH_TEMPLATE_QUEUE, durable = "true", autoDelete = "true", arguments = @Argument(name = "x-queue-mode", value = "lazy")),
        exchange = @Exchange(value = WECHAT_BATCH_TEMPLATE_EXCHANGE)
))
public class WechatBatchTemplateConsumer {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private PayMessageTemplateService payMessageTemplateService;
    @Autowired
    private ConsumerLogService consumerLogService;


    /**
     * 消费者订阅微信模板队列主题  调用 微信公众号模板接口
     */
    @RabbitHandler
    public void process(String msg, Message message, Channel channel) throws IOException {
        log.info(">>调用微信模板接口发送微信模板提醒:{}<<", msg);
        try {
            // 将一个msg 拆分多个msg
            List<NotifyMerchantBO> notifyMerchantBOs = JSONUtil.toList(msg, NotifyMerchantBO.class);
            notifyMerchantBOs.forEach((notifyMerchant) -> {
                // 根据每个子消息查询是否消费成功过，如果没有消费成功的情况下 接受重试
                String msgId = notifyMerchant.getPaymentId();
                ConsumerLog consumerLog = consumerLogService.getByMsgIdConsumerLog(msgId);
                if (consumerLog == null) {
                    //1.调用第三方微信公众号模板接口
                    //2.该方法返回值true 手动ack成功 返回false手动ack失败 需要MQ给我们消费者补偿
                    boolean result = payMessageTemplateService.notifyMerchantPaymentResult(notifyMerchant);
                    if (!result) {
                        //返回false手动ack失败 需要MQ给我们消费者补偿
                        log.error("[调用消息模板接口发送消息失败,notifyMerchantBO:{}]", notifyMerchant);
                        // 如何发生了异常，将该子msg存入到死信队列中
                        rabbitTemplate.convertAndSend(RETRY_EXCHANGE, "", msg);
                        log.info("消费者消费该msg:{}多次失败，将msg存放死信队列中", msg);
                    }
                }
            });
        } catch (Exception e) {
            log.error("e:{}", e);
            // 1. 记录重试次数 重试多次还是失败的情况下  将批量msg 写日志表 死信队列
            // 让MQ来一次重试
            throw new RuntimeException(e);
        }
    }
}
